Passed
Push — master ( 8d27c4...160b88 )
by Miloš
02:58
created

ReliableSocketRequestEmitter   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 118
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 87
dl 0
loc 118
rs 10
c 0
b 0
f 0
wmc 9

5 Functions

Rating   Name   Duplication   Size   Complexity  
A removeFromEmitQueue 0 7 1
A createEmitPromise 0 18 1
B emitRequest 0 33 5
A createEmitPack 0 14 1
A emit 0 27 1
1
import { InQueueType } from "../enums/in-queue-type";
2
import { IReliableSocketEmitOptions } from "../interfaces/i-reliable-socket-emit-options";
3
import { IReliableSocketRequest } from "../interfaces/i-reliable-socket-request";
4
import { IReliableSocketRequestPack } from "../interfaces/i-reliable-socket-request-pack";
5
import { IReliableSocketRequestQueues } from "../interfaces/i-reliable-socket-request-queues";
6
import { ISocketEmitter } from "../interfaces/i-socket-emitter";
7
8
export class ReliableSocketRequestEmitter {
9
    private defaultEmitOptions = {
10
        inQueueType: InQueueType.anytime,
11
        maxTryCount: 0,
12
        queueName: "default",
13
        retryTime: 1000,
14
    };
15
    private emitQueues: IReliableSocketRequestQueues = {
16
        default: [],
17
    };
18
    private emitRequestCounter = 0;
19
20
    public emit(
21
        socket: ISocketEmitter,
22
        eventName: string,
23
        emitDataPack: any,
24
        optionsIn: Partial<IReliableSocketEmitOptions> = this
25
            .defaultEmitOptions,
26
    ): Promise<any> {
27
        const options: IReliableSocketEmitOptions = Object.assign(
28
            {},
29
            this.defaultEmitOptions,
30
            optionsIn,
31
        );
32
33
        const socketRequest = {
34
            eventName,
35
            id: this.emitRequestCounter++,
36
            isCompleted: false,
37
            options,
38
            socket,
39
        } as IReliableSocketRequest;
40
41
        this.emitQueues[options.queueName].push(socketRequest);
42
43
        emitDataPack.requestCounter = this.emitRequestCounter;
44
45
        return this.createEmitPromise(socket, socketRequest, options);
46
    }
47
48
    private removeFromEmitQueue(socketRequest: IReliableSocketRequest) {
49
        this.emitQueues[socketRequest.options.queueName].splice(
50
            this.emitQueues[socketRequest.options.queueName].indexOf(
51
                socketRequest,
52
            ),
53
            1,
54
        );
55
    }
56
57
    private createEmitPromise(
58
        socket: ISocketEmitter,
59
        socketRequest: IReliableSocketRequest,
60
        options: IReliableSocketEmitOptions,
61
    ): Promise<any> {
62
        return new Promise(resolve => {
63
            socketRequest.isCompleted = false;
64
65
            this.emitRequest(socket, socketRequest, response => {
66
                resolve(response);
67
            });
68
69
            socketRequest.interval = setInterval(() => {
70
                this.emitRequest(socket, socketRequest, response => {
71
                    resolve(response);
72
                });
73
            }, options.retryTime);
74
        });
75
    }
76
77
    /**
78
     * Emit the request in a package and mark as completed if success
79
     */
80
    private emitRequest(
81
        socket: ISocketEmitter,
82
        socketRequest: IReliableSocketRequest,
83
        callback: (response: any) => void,
84
    ): void {
85
        if (socketRequest.isCompleted) {
86
            if (socketRequest.interval) {
87
                clearInterval(socketRequest.interval);
88
            }
89
            return;
90
        }
91
92
        if (socket) {
93
            socket.emit(
94
                socketRequest.eventName,
95
                this.createEmitPack(socketRequest, socketRequest.options),
96
                (response: any) => {
97
                    socketRequest.isCompleted = true;
98
                    this.removeFromEmitQueue(socketRequest);
99
100
                    if (socketRequest.interval) {
101
                        clearInterval(socketRequest.interval);
102
                    }
103
104
                    callback(response);
105
                },
106
            );
107
        } else {
108
            throw Error("No provided socket!");
109
        }
110
    }
111
112
    /**
113
     * Create transfer package with meta information
114
     */
115
    private createEmitPack(
116
        data: any,
117
        options: IReliableSocketEmitOptions,
118
    ): IReliableSocketRequestPack {
119
        return {
120
            body: data,
121
            meta: {
122
                id: this.emitRequestCounter,
123
                inQueueType: options.inQueueType,
124
                queueName: options.queueName,
125
            },
126
        };
127
    }
128
}
129